#ifndef FEEDER_AGENT_H_
#define FEEDER_AGENT_H_

#include "Agent.h"
#include "Feeder.h"
#include "Structs.h"
#include "Enums.h"
#include "GUIFeeder.h"
#include "Lane.h"
#include "Gantry.h"
#include <string>
#include <list>
#include "Lock.h"

class Agent;
class Feeder;
class GUIFeeder;
class Lane;
class Gantry;
class Lock;

struct PartRecipe;
struct FeederOrder;

/**
 * @class	FeederAgent
 *
 * @brief	Feeder agent.
 *
 * @author	Graham Matuszewski
 */

class FeederAgent : public Feeder, public Agent {

	private:
	//Gui

	GUIFeeder* guiFeeder;
	Lane* topLane;
	Lane* bottomLane;
	Gantry*    gantry;
	std::list<PartRecipe>* partOrders;
	PartRecipe currentRecipe;
	enum FeederStatus{IDLE,PURGE,MOVING,GUI};
	FeederStatus state;
	bool giveGantryStatus;
	int currentLane;
	Lock FeederLock;
	//std::string name;

	public:
	int PullInMyLibrary() { return 0; };
	//Constructors
	FeederAgent(std::string myname);
	~FeederAgent(){};

	//Messages
	void msgPleaseGetParts(PartType newPartType,Lane* newLane); //called by Lane
	void msgHereAreParts(PartRecipe recipe); //called by Gantry
	void msgGUIHasMovedPart(); //called by GUI
	void msgPurgeParts(); //called by ITSELF
	void msgGUIHasPurged(); //called by GUI
	void msgCurrentStatus(); //called by Gantry
	

	//Schedule
	virtual bool pickAndExecuteAnAction();


	//Actions
	void notifyPurge();
	void notifyGantry();
	void moveGuiToLane();
	void giveStatusToGantry();

	//other
	bool guiStatus();
	bool purgeStatus();
	bool movingStatus();

	void setGantry(Gantry* newGantry);
	void setLaneTop(Lane* laneTop);
	void setLaneBottom(Lane* laneBottom);
	void setGUIFeeder(GUIFeeder* gui);

	Gantry* getGantryAgent();
	
	Lane* getBottomAgent();
	Lane* getTopAgent();
	
	GUIFeeder* getGUI();

	std::string toString() const;

	int partOrdersSize();
	PartRecipe getTopRecipe();

	void handleBreak();
	void handleFix();

protected:
	

};

#endif